#include "mmu.h"
#include "i386.h"

//////////////////////////////////////////////
//Variables globales para el manejo de memoria
void * usuarioLibre;
unsigned int pagUsuario;
void * kernelLibre;
unsigned int pagKernel;
/////////////////////////////////////////////

void inicializar_mmu(){
	//última página de usuario libre
	usuarioLibre = (void*)INICIO_PAGINAS_USUARIO;
	//Cantidad de páginas de usuario libre
	pagUsuario=CANTIDAD_PAGINAS_USUARIO;

	//última página de kernel libre
	kernelLibre = (void*)INICIO_PAGINAS_KERNEL;
	//Cantidad de páginas de kernel libre
	//pagKernel=CANTIDAD_PAGINAS_USUARIO;
	pagKernel=CANTIDAD_PAGINAS_KERNEL;	
}


unsigned int *pagina_libre_kernel(){
	unsigned int *entrego;

	if(pagKernel == 0) return 0;
	
	//si no tengo más páginas devuelvo error (0)
	entrego=(unsigned int *)0;
	if(pagKernel--){
		entrego=kernelLibre;
		kernelLibre+=TAMANO_PAGINA;
	}
		
	return entrego;
}

unsigned int *pagina_libre_usuario(){
	unsigned int *entrego;
	
	if(pagUsuario == 0) return 0;

	//si no tengo más páginas devuelvo error (0)
	entrego=(unsigned int *)0;
	if(pagUsuario--){
		entrego=usuarioLibre;
		usuarioLibre+=TAMANO_PAGINA;
	}
	
	return entrego;	
}


unsigned int* inicializar_dir_kernel(){
		unsigned int baseK = 0;
		unsigned int i;
		
		unsigned int *dirbase =(unsigned int *) 0x00100000;		
		//Uso una pagina de kernel para el directorio de tablas de páginas
		//incremento el puntero a la última página de kernel libre
		kernelLibre+=TAMANO_PAGINA;
		pagKernel--;
		unsigned int *tablebase =(unsigned int *) 0x00101000;
		//Uso una pagina de kernel para la tabla de páginas
		//incremento el puntero a la última página de kernel libre
		kernelLibre+=TAMANO_PAGINA;
		pagKernel--;
		
		//La entrada de directorio apunta a una tabla con atributos: SUPERVISOR,LECTURA_ESCRITURA, PRESENTE
		*dirbase =((unsigned int) tablebase | SUPERVISOR|LECTURA_ESCRITURA|PRESENTE);
		////dirbase++;

		//Entradas de tabla de páginas para páginas de kernel
		for(baseK=0; baseK < DIR_4MB; baseK += TAMANO_PAGINA) {
			*tablebase =(baseK | PRESENTE|LECTURA_ESCRITURA|SUPERVISOR);
			tablebase++;
		}

		for(i=1; i<16; i++) { 
				//Entradas de tabla de páginas para páginas de 4 megas del kernel
				// extender_dir_kernel
				//La entrada de directorio apunta a una tabla con atributos: SUPERVISOR,LECTURA_ESCRITURA, PRESENTE
				dirbase[i] = ((unsigned int) (i*TAMANO_PAGINA_4MB) | SIZE_PAGE_4MB | SUPERVISOR|LECTURA_ESCRITURA|PRESENTE);
		}

		
		for(i=16;i<0x400;i++){
			//inicializo las entradas restantes del directorio. 
			//Si la entrada está NO_PRESENTE la tabla de páginas no existe y hay que crearla
			dirbase[i] =((unsigned int) 0 | NO_PRESENTE);
		}
		
		
		
		//devuelvo la base del directorio de páginas
		return (unsigned int*)0x00100000;
}



